package base.world;

import java.util.ArrayList;
import java.util.Random;

import base.Start;
import base.common.IInput;
import base.common.ILiving;
import base.common.IRender;
import base.engine.RenderHandler;

public abstract class World
{
	/**List of ILiving to be spawned at the beginning of every tick and disposed afterwards*/
	protected ArrayList<ILiving> spawnList = new ArrayList<ILiving>();
	/**List of ILiving currently in world*/
	public ArrayList<ILiving> livingList = new ArrayList<ILiving>();
	/**List of ILiving to be disposed at the end of every tick*/
	protected ArrayList<ILiving> trashList = new ArrayList<ILiving>();

	public boolean isDead = false;

	public Random rand = new Random();

	/**Initiates world*/
	public abstract void initWorld();

	/**Main update for world*/
	public void updateWorld()
	{
		for (ILiving obj : this.spawnList)
		{
			obj.onInit();
			this.livingList.add(obj);
		}

		this.spawnList.clear();

		for(ILiving obj : this.livingList)
		{
			if (!obj.isDead() && obj != null)
			{
				obj.onUpdate();
			}
			else
			{
				this.trashList.add(obj);
			}
		}

		this.clearTrash();
	}

	/**Main render for world*/
	public void render()
	{
		for(ILiving obj : this.livingList)
		{
			if (!obj.isDead())
			{
				if (Start.isDebugMode)
				{
					RenderHandler.getRenderFromMap(null).onRender(obj);
				}
				else
				{
					IRender render = RenderHandler.getRenderFromMap(obj.getClass());
					if (render != null)
					{
						render.onRender(obj);
					}
					else
					{
						RenderHandler.getRenderFromMap(null).onRender(obj);
					}
				}
			}
		}
	}

	/**Main disposal for world*/
	protected void clearTrash()
	{
		for(ILiving obj : this.trashList)
		{
			obj.onDestroy();
			this.livingList.remove(obj);
		}

		this.trashList.clear();
	}

	/**Add ILiving to spawn list and register with InputHandler if implements IInput*/
	public ILiving addLiving(ILiving par1ILiving)
	{
		if (par1ILiving != null)
		{
			this.spawnList.add(par1ILiving);
			if (par1ILiving instanceof IInput)
			{
				Start.inputManager.registerInput((IInput) par1ILiving);
			}
		}
		return par1ILiving;
	}

	/**Add list of ILiving to spawn list and register with InputHandler if implements IInput*/
	public ILiving[] addLiving(ILiving[] par1ILiving)
	{
		for (int i = 0; i < par1ILiving.length; i++)
		{
			if (par1ILiving[i] != null)
			{
				this.spawnList.add(par1ILiving[i]);
				if (par1ILiving[i] instanceof IInput)
				{
					Start.inputManager.registerInput((IInput) par1ILiving[i]);
				}
			}
		}
		return par1ILiving;
	}

	/**End world and dispose all instances*/
	public void terminateWorld()
	{
		this.isDead = true;

		for (ILiving obj : this.livingList)
		{
			this.trashList.add(obj);
		}

		this.spawnList.clear();
		this.clearTrash();
	}
}
